home *** CD-ROM | disk | FTP | other *** search
- ; This is the snake game...
- ;
- ; It's better to set the
- ; "step delay" to "0" before
- ; running, it requires fast
- ; processing.
- ;
- ; You can control the snake
- ; using arrow keys on your
- ; keyboard.
- ;
- ; All other keys will stop
- ; the snake.
- ;
- ; Press ESC to exit.
-
-
- #make_COM#
-
- ORG 100h
-
- ; jump over data section:
- JMP start
-
- ; ------ DATA section ------
-
- s_size EQU 7
-
- ; the snake coordinates
- ; (from head to tail)
- ; low byte is left, high byte
- ; is top - [top, left]
- snake DW s_size DUP(0)
-
- tail DW ?
-
- ; direction constants
- ; (BIOS key codes):
- LEFT EQU 4Bh
- RIGHT EQU 4Dh
- UP EQU 48h
- DOWN EQU 50h
-
- ; current snake direction:
- cur_dir DB RIGHT
-
- wait_time DW 0
-
- ; ------ CODE section ------
-
- start:
-
- CALL SayThis
- DB "==== HOW TO PLAY ====", 13, 10
- DB "It's better to set the", 13, 10
- DB '"step delay" to "0" before', 13, 10
- DB "running, it requires fast", 13, 10
- DB "processing.", 13, 10, 13, 10
-
- DB "You can control the snake", 13, 10
- DB "using arrow keys on your", 13, 10
- DB "keyboard.", 13, 10, 13, 10
-
- DB "All other keys will stop", 13, 10
- DB "the snake.", 13, 10, 13, 10
-
- DB "Press ESC to exit.", 13, 10
- DB "====================", 13, 10, 13, 10
- DB "Press any key to start...", 0
-
-
- ; wait for any key:
- MOV AH, 00h
- INT 16h
-
-
- ; hide text cursor:
- ; (emulator shows
- ; text cursor only when
- ; it wait for input, so
- ; this is optional)
- MOV AH, 1
- MOV CH, 2Bh
- MOV CL, 0Bh
- INT 10h
-
-
- game_loop:
-
- ; === select first video page
- MOV AL, 0 ; page number.
- MOV AH, 05h
- INT 10h
-
- ; === show new head:
- MOV DX, snake[0]
-
- ; set cursor at DL,DH
- MOV AH, 02h
- INT 10h
-
- ; print '*' at the location:
- MOV AL, '*'
- MOV AH, 09h
- MOV BL, 0Eh ; attribute.
- MOV CX, 1 ; single char.
- INT 10h
-
- ; === keep the tail:
- MOV AX, snake[s_size * 2 - 2]
- MOV tail, AX
-
- CALL move_snake
-
-
- ; === hide old tail:
- MOV DX, tail
-
- ; set cursor at DL,DH
- MOV AH, 02h
- INT 10h
-
- ; print ' ' at the location:
- MOV AL, ' '
- MOV AH, 09h
- MOV BL, 0Eh ; attribute.
- MOV CX, 1 ; single char.
- INT 10h
-
-
-
- check_for_key:
-
- ; === check for player commands:
- MOV AH, 01h
- INT 16h
- JZ no_key
-
- MOV AH, 00h
- INT 16h
-
- CMP AL, 1Bh ; ESC - key?
- JE stop_game ;
-
- MOV cur_dir, AH
-
- no_key:
-
-
-
- ; === wait a few moments here:
- ; get number of clock ticks
- ; (about 18 per second)
- ; since midnight into CX:DX
- MOV AH, 00h
- INT 1Ah
- CMP DX, wait_time
- JB check_for_key
- ADD DX, 4
- MOV wait_time, DX
-
-
-
- ; === eternal game loop:
- JMP game_loop
-
-
- stop_game:
-
- ; show cursor back:
- MOV AH, 1
- MOV CH, 0Bh
- MOV CL, 0Bh
- INT 10h
-
- RET
-
- ; ------ functions section ------
-
- ; This procedure creates the
- ; animation by moving all snake
- ; body parts one step to tail,
- ; the old tail goes away:
- ; [Last part (tail)]-> goes away
- ; [Part i] -> [Part i+1]
- ; ....
-
- move_snake PROC NEAR
-
- ; set ES to BIOS info segment:
- MOV AX, 40h
- MOV ES, AX
-
- ; point DI to tail
- MOV DI, s_size * 2 - 2
- ; move all body parts
- ; (last one simply goes away)
- MOV CX, s_size-1
- move_array:
- MOV AX, snake[DI-2]
- MOV snake[DI], AX
- SUB DI, 2
- LOOP move_array
-
-
- CMP cur_dir, LEFT
- JE move_left
- CMP cur_dir, RIGHT
- JE move_right
- CMP cur_dir, UP
- JE move_up
- CMP cur_dir, DOWN
- JE move_down
-
- JMP stop_move ; no direction.
-
-
- move_left:
- MOV AL, b.snake[0]
- DEC AL
- MOV b.snake[0], AL
- CMP AL, -1
- JNE stop_move
- MOV AL, ES:[4Ah] ; col number.
- DEC AL
- MOV b.snake[0], AL ; return to right.
- JMP stop_move
-
- move_right:
- MOV AL, b.snake[0]
- INC AL
- MOV b.snake[0], AL
- CMP AL, ES:[4Ah] ; col number.
- JB stop_move
- MOV b.snake[0], 0 ; return to left.
- JMP stop_move
-
- move_up:
- MOV AL, b.snake[1]
- DEC AL
- MOV b.snake[1], AL
- CMP AL, -1
- JNE stop_move
- MOV AL, ES:[84h] ; row number -1.
- MOV b.snake[1], AL ; return to bottom.
- JMP stop_move
-
- move_down:
- MOV AL, b.snake[1]
- INC AL
- MOV b.snake[1], AL
- CMP AL, ES:[84h] ; row number -1.
- JBE stop_move
- MOV b.snake[1], 0 ; return to top.
- JMP stop_move
-
- stop_move:
- RET
- move_snake ENDP
-
-
-
- ; Procedure to print a null terminated
- ; string at current cursor position.
- ; The ZERO TERMINATED string should be
- ; defined just after the CALL.
- ; For example:
- ;
- ; CALL SayThis
- ; db 'Hello World!', 0
- ;
- ; Address of string is stored in the Stack
- ; as return address.
- ; Procedure updates value in the Stack to
- ; make return after string definition.
- SayThis PROC NEAR
-
- MOV CS:temp1, SI ; re-store SI register.
-
- POP SI ; get return address (IP).
-
- PUSH AX ; store AX register.
-
- next_char:
- MOV AL, CS:[SI]
- INC SI ; next byte.
- CMP AL, 0
- JZ printed
- MOV AH, 0Eh ; teletype function.
- INT 10h
- JMP next_char ; loop.
- printed:
-
- POP AX ; re-store AX register.
-
- ; SI should point to next command after
- ; the CALL instruction and string definition:
- PUSH SI ; save new return address into the Stack.
-
- MOV SI, CS:temp1 ; re-store SI register.
-
- RET
- temp1 DW ? ; variable to store original value of SI register.
- SayThis ENDP
-
-
-
- END
-